package com.istock.union.user.client;

import org.springframework.util.StringUtils;

import com.istock.base.serializer.json.TypeReference;
import com.istock.union.user.model.SSOUser;
import com.istock.union.user.service.StorageService;

/**
 * 存取sso信息的入口
 * 只保存和登录用户有关的信息
 * 
 * @author senvon
 *
 */
public class SSOClientUtils {

	private static SSOClientUtils instance = null;
	
	private StorageService storageService;
	
	public StorageService getStorageService() {
		return storageService;
	}

	public void setStorageService(StorageService storageService) {
		this.storageService = storageService;
	}

	/**
	 * 对登录用户,存储一个大的key,存储结构如下
	 * key=_USER_ssoUser.tenantCode+ssoUser.userName
	 * key:{
	 *  ,"PC":[token1,token2]
	 *  ,"MOBLIE":[token3,token4]
	 * }
	 */
	public static final String KEY_SSO_USER = "_USER_";
	
	/**
	 * 存储token的缓存,使用token作为key
	 * token:{
	 * ssoUser
	 * deivceIp:[ip1,ip2]
	 * }
	 */
	public static final String KEY_TOKEN = "_TOKEN";
	
	public static final String USER_TOKEN_LIST = "_TOKEN";
	
	private SSOClientUtils() {
		
	}
	
	public static SSOClientUtils getInstance() {
		if(instance == null) {
			synchronized(SSOClientUtils.class) {
				if(instance == null) {
					instance = new SSOClientUtils();
				}
			}
		}
		return instance;
	}
	
	private ThreadLocal<String> curToken= new ThreadLocal<String>();
	
	/**filter每次获取到登录信息,都对token进行赋值
	 * 方便使用SSOClientUtils.getInstance().getxxx() 直接获取存储的信息
	 * 
	 * 对于param的数据,这边已经对token进行了设置,所有的参数获取如果使用get方式调用的话,直接获取缓存
	 * 没有必要对其余参数进行设置
	 * @param token
	 */
	public void setCurrent(String token ) {
		curToken.set(token);
	}
	
	public void clear() {
		curToken.remove();
	}
	
	/**得到当前登录的用户信息
	 * @return
	 */
	public SSOUser findCurrentUser() {
		if(curToken.get() != null) {
			String tokenKey = SSOClientUtils.KEY_TOKEN+curToken.get();
			return storageService.getObject(curToken.get() , tokenKey, new TypeReference<SSOUser>() {});
		}
		return null;
	}
	
	//存储/获取缓存值
	//这个缓存和当前登录用户绑定,如果当前登录用户失效,则缓存失效
	//可以把整个缓存看成是session的操作
	/**类似session的操作.
	 * 当session失效,存储的所有内容都会失效
	 * 存储一个值
	 * @param key
	 * @param obj
	 */
	public void putObject(String key , Object obj) {
		if(StringUtils.hasLength(curToken.get())) {
			storageService.putObject(curToken.get(), key, obj);
		}
	}
	
	public void removeObject(String key) {
		if(StringUtils.hasLength(curToken.get())) {
			storageService.removeObject(curToken.get(), key);
		}
	}
	
	/**类似session的操作,获取一个值
	 * @param key
	 * @param typeReference
	 * @return
	 */
	public <T> T getObject(String key , TypeReference<T> typeReference) {
		if(StringUtils.hasLength(curToken.get())) {
			return storageService.getObject(curToken.get(), key, typeReference);
		}
		return null;
	}
	
	/**检查当前的用户是否具备permiss的权限.
	 * @param permiss
	 * @return
	 */
	public boolean hasPermiss(String permiss) {
		SSOUser ssoUser = findCurrentUser();
		if(ssoUser != null) {
			return ssoUser.getPermissions().contains(permiss);
		}
		return false;
	}
	
	public boolean isAdmin(){
		return "admin".equalsIgnoreCase(findCurrentUser().getLoginName());
	}
	
}
